#pragma once
//模拟阻塞队列
#include<iostream>
#include<queue>
#include<pthread.h>
using namespace std;

template<class T>
class BlockQueue
{
    static const int defaultnum=0;
public:
    BlockQueue<T>(int maxcp=defaultnum):maxcp_(maxcp)
    {
        pthread_mutex_init(&mutex_,nullptr);
        pthread_cond_init(&c_cond_,nullptr);
        pthread_cond_init(&p_cond_,nullptr);
    }



    T pop()
    {
        pthread_mutex_lock(&mutex_);
        if(q_.size()==0)
        {
            pthread_cond_wait(&c_cond_,&mutex_);
        }
        T out=q_.front();
        q_.pop();
        pthread_cond_signal(&c_cond_);
        pthread_mutex_unlock(&mutex_);
        return out;
    }
    void push(const T &in)
    {
        pthread_mutex_lock(&mutex_);
        //判断大小是否等于极值

        if(q_.size()==maxcp_)//等待
        {
            pthread_cond_wait(&p_cond_,&mutex_);//调用的时候 释放锁 唤醒而返回后重新持有锁
        }
        //队列没满 被唤醒
        q_.push(in);
        pthread_mutex_unlock(&mutex_);
    }
    ~BlockQueue()
    {
        pthread_mutex_destroy(&mutex_);
        pthread_cond_destroy(&c_cond_);
        pthread_cond_destroy(&p_cond_);

    }

private:
    std::queue<T> q_;  //共享资源
    int maxcp_;    //极值
    pthread_mutex_t mutex_;
    pthread_cond_t c_cond_;
    pthread_cond_t p_cond_;

    // void push(const T &in)
    // {
    //     pthread_mutex_lock(&mutex_);
    //     //判断大小是否等于极值

    //     if(q_.size()==maxcp_)//等待
    //     {
    //         pthread_cond_wait(&p_cond_,&mutex_);//调用的时候 释放锁
    //     }
    //     //队列没满 被唤醒
    //     q_.push(in);
    //     pthread_mutex_unlock(&mutex_);
    // }

    // T pop()
    // {
    //     pthread_mutex_lock(&mutex_);
    //     if(q_.size()==0)
    //     {
    //         pthread_cond_wait(&c_cond_,&mutex_);
    //     }
    //     T out=q_.front();
    //     q_.pop();
    //     pthread_cond_signal(&c_cond_);
    //     pthread_mutex_unlock(&mutex_);
    //     return out;
    // }
};